#ifndef _ABSTRACTDATATABLE_H_
#define _ABSTRACTDATATABLE_H_

#include <buildspec.h>
#include <exceptions/GSTRuntimeException.h>
#include <Client/ClientUtils/Network/RDBAttribute.h>

#include <typeinfo>
#include <string>
#include <boost/any.hpp>
#include <boost/lexical_cast.hpp>

namespace GST {
namespace ClientUtils {

	/**
	 * It derived classes hides the return structures of the DB.
	 */
	class GST_API_EXPORT AbstractDataTable
	{
	public:

		virtual ~AbstractDataTable() { }
		virtual AbstractDataTable& operator=(const AbstractDataTable& other) 
		{
			if (this != &other) 
			{

			}
			return *this;
		};
		template<typename T> T getAs(int col);
		template<typename T> T getAsFromBinary(int col);
		
		///@name getter
		//@{
		virtual boost::any get(const std::type_info& returntype, int col) = 0;
		virtual bool isNull(int col) = 0;
		virtual std::string getName(int col) const = 0;
		virtual TableAttributeDesc::DType getType(int col) const = 0;
		virtual int getDimension(int col) const = 0;
		virtual bool isNullable(int col) const = 0;
		virtual bool nextRow() = 0;
		virtual unsigned int cols() const = 0;
		//@}

		///@name not in interface anymore
		//@{
		//not in interface due delete of rows(): template<typename T> T getAs(int row, int col);
		//not in interface due delete of rows(): virtual boost::any get(const std::type_info& returntype, int row, int col) = 0;
		//not in interface due delete of get(int,int): virtual bool isNull(int row, int col) = 0;
		//not in interface due to OTL stream: virtual unsigned int rows() const = 0;
		//not in interface due delete of rows(): virtual boost::any get(const TableAttributeDesc::DType& type, int row, int col);
		//@}

		///@name polymorphic use; predefined
		//@{
		virtual boost::any get(const TableAttributeDesc::DType& type, int col);
		virtual AbstractRDBAttributeDescPtr getAttributeDesc(int col) const;
		virtual RDBAttributeDescListPtr getAttributeDescs() const;
		//@}

	protected:
		virtual AbstractRDBAttributeDesc * newAttributeDesc(int col) const;
		virtual AbstractRDBAttributeDesc * newAttributeDesc(const TableAttributeDesc & desc, bool is_primaryKey=false) const = 0;
	};

	//typedefs of class or members:
	typedef boost::shared_ptr<AbstractDataTable> AbstractDataTablePtr;

	//template implementations:
	template<typename T> 
	T
	AbstractDataTable::getAs(int col)
	{
		return boost::any_cast<T>(this->get(typeid(T),col));
	}
	template<typename T>
	T
	AbstractDataTable::getAsFromBinary(int col)
	{
		return boost::any_cast<T>(this->get(typeid(const char*),col));
	}
	

} //of ns ClientUtils
} //of ns GST

#endif //_ABSTRACTDATATABLE_H_
